/*
		串口数据接收模块使用说明：	
					数据的发送：
							1. bit_select 比特率设计  1 ：9600		2 ：19200		3 ：38400		4 ：57200		5 ：115200
							2. rxd 为外部发送进来的串行数据
							3. data_accept 为接收到的并行数据
*/

module uart_accept(

	input		wire				clk			,									//系统时钟信号：50M
	input		wire 				ret_n			,									//复位信号
	input		wire	[2:0]		bit_select	,									//比特率选择信号
	input		wire				rxd			,									//接收的串行数据信号
	
	output	reg	[7:0]		data_accept	,									//接收的并行数据信号
	output	reg				uart_end

);

	reg	[1:0]		metasable_state;				//消除按键输入的亚稳态
	reg 	[1:0]		nedge_txd;						//数据寄存，用于判断数据开始
		
	reg	[2:0]		bit_select_judge;				//对比特率选择信号进行寄存
	reg 	[12:0]	cnt_bit_max;					//比特计数器计数的最大值，用于比特率的选择
	reg				cnt_bit_en;						//比特计数器开始的使能信号，用于判断数据传入的第几位
	reg	[4:0]		cnt_bit_collect;				//用来判断比特计数器使能信号是否有效
	reg 	[12:0]	cnt_bit;							//比特计数器
		
	reg	[11:0]	cnt_bit_change_max;			//比特四分频计数器计数最大值
	reg				cnt_bit_change_en;			//对传输的数据提取和接收的使能信号
	reg 	[11:0]	cnt_bit_change_four;			//比特四分频计数器，将传输的信号进行拆分为4段，对其中的两段稳定信号进行提取判断
	reg	[1:0]		cnt_bit_change;				//比特四分频计数器，将数据的数据分成4分，进行提取判断
	
	reg 	[8:0]		cnt_collect_judge_max;		//比特十六分频计数器计数最大值		
	reg	[8:0]		cnt_collect_judge;			//采集数据计数器
	reg 	[2:0]		cnt_collect;					//采集的次数
	reg	[3:0]		collect_judge;					//传入数据判断信号，判断数据是：1 or 0
	reg	[7:0]		collect_data;					//数据收集信号
		
	wire				nedge;							//数据传输开始标志信号	高电平有效


	/*
		以下为：对数据的亚稳态和数据开始传输信号的设计
	*/
	
	//消除数据采集的亚稳态问题
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			begin 
				metasable_state[0] <= 0;
				metasable_state[1] <= 0;
			end 
		else 
			begin 
				metasable_state[0] <= rxd;
				metasable_state[1] <= metasable_state[0];
			end 
		
	//对传入的数据进行判断
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			begin 
				nedge_txd[0] <= 0;
				nedge_txd[1] <= 0;
			end 
		else 
			begin 
				nedge_txd[0] <= metasable_state[1];
				nedge_txd[1] <= nedge_txd[0];
			end 
				
	//对 nedge 数据传输开始标志信号进行编写	高电平有效
	assign nedge = nedge_txd[1] && ! nedge_txd[0];
	
	
	
	/*
		以下为：对数据传输信号的结束和开始接收的使能信号进行设计
	*/
	
	
	//对 bit_select 比特选择信号进行寄存一拍
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			bit_select_judge <= 3'd0;
		else 
			bit_select_judge <= bit_select;

	//对 cnt_bit_max 比特率最大值进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_bit_max <= 13'd0;
		else 
			case(bit_select_judge)
					1 	:	cnt_bit_max <= 13'd5208;
					2	:	cnt_bit_max <= 13'd2604;
					3	:	cnt_bit_max <= 13'd1302;
					4	:	cnt_bit_max <= 13'd868;
					5	:	cnt_bit_max <= 13'd54;
				default	: cnt_bit_max <= 13'd0;
			endcase 
			
	//对 cnt_bit_en 传输的数据计数器使能信号进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_bit_en <= 1'b0;
		else if(nedge)
			cnt_bit_en <= 1'b1;
		else if((cnt_bit_collect == 9) && (cnt_bit == cnt_bit_max - 1))
			cnt_bit_en <= 1'b0;
		else 
			cnt_bit_en <= cnt_bit_en;
			
	//对 cnt_bit 比特计数器进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_bit <= 13'd0;
		else if(cnt_bit_en == 1'b1)
			begin 
				if(cnt_bit == cnt_bit_max - 1)
					cnt_bit <= 13'd0;
				else 
					cnt_bit <= cnt_bit + 1'b1;
			end 
		else 
			cnt_bit <= 13'd0;
			
	//对 cnt_bit_collect 判断比特计数器使能信号是否有效信号进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_bit_collect <= 5'd0;
		else if(cnt_bit_en == 1'b1)
			begin 
				if((cnt_bit_collect == 5'd9) && (cnt_bit == cnt_bit_max - 1))
					cnt_bit_collect <= 5'd0;
				else if(cnt_bit == cnt_bit_max - 1) 
					cnt_bit_collect <= cnt_bit_collect + 1'b1;
				else 
					cnt_bit_collect <= cnt_bit_collect;
			end 
		else 
			cnt_bit_collect <= 5'd0;
	
	
	/*
		以下为：对传输的数据进行提取 
	*/
	
	
	//对 cnt_bit_change_max	比特四分频计数器计数最大值进行编写，用于将传输的信号进行拆分为4段，对其中的两段稳定信号进行提取判断
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_bit_change_max <= 12'd0;
		else 
			cnt_bit_change_max <= cnt_bit_max >> 2;
		
	//对 cnt_bit_change_en 传输的数据提取和接收的使能信号，同时也是拆分计数器的使能信号
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_bit_change_en <= 1'b0;
		else if(cnt_bit_en == 1'b1)
			begin 
				if(cnt_bit_change == 2'd1)
					cnt_bit_change_en <= 1'b1;
				else if(cnt_bit_change == 2'd3)
					cnt_bit_change_en <= 1'b0;
				else 
					cnt_bit_change_en <= cnt_bit_change_en;
			end 
		else 
			cnt_bit_change_en <= 1'b0;
			
	//对 cnt_bit_change_four 比特四分频计数器进行编写，将传输的信号进行拆分为4段，对其中的两段稳定信号进行提取判断
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_bit_change_four <= 12'd0;
		else if(cnt_bit_en == 1'b1)
			begin 
				if(cnt_bit_change_four == cnt_bit_change_max - 1)
					cnt_bit_change_four <= 12'd0;
				else 
					cnt_bit_change_four <= cnt_bit_change_four + 1'b1;
			end 
		else 
			cnt_bit_change_four <= 12'd0;
			
	//对 cnt_bit_change 比特四分频计数器进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_bit_change <= 2'd0;
		else if(cnt_bit_en == 1'b1)
			begin 
				if((cnt_bit_change == 2'd3) && (cnt_bit_change_four == cnt_bit_change_max - 1))
					cnt_bit_change <= 2'd0;
				else if(cnt_bit_change_four == cnt_bit_change_max - 1)
					cnt_bit_change <= cnt_bit_change + 1'b1;
				else 
					cnt_bit_change <= cnt_bit_change;
			end 
		else 
			cnt_bit_change <= 2'd0;
			
	//对 cnt_collect_judge_max 比特十六分频计数器计数最大值进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_collect_judge_max <= 9'd0;
		else 
			cnt_collect_judge_max <= cnt_bit_max >> 4;
			
	//对 cnt_collect_judge 	采集数据计数器进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_collect_judge <= 9'd0;
		else if(cnt_bit_change_en == 1'b1)
			begin 
				if(cnt_collect_judge == cnt_collect_judge_max - 1)
					cnt_collect_judge <= 9'd0;
				else 
					cnt_collect_judge <= cnt_collect_judge + 1'b1;
			end 
		else 
			cnt_collect_judge <= 9'd0;
			
	//对 cnt_collect 采集次数信号进行编写
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			cnt_collect <= 3'd0;
		else if(cnt_bit_change_en == 1'b1)
			begin 
				if((cnt_collect == 3'd7) && (cnt_collect_judge == cnt_collect_judge_max - 1)) 
					cnt_collect <= 3'd0;
				else if(cnt_collect_judge == cnt_collect_judge_max - 1)
					cnt_collect <= cnt_collect + 1'b1;
				else 
					cnt_collect <= cnt_collect;
			end 
		else 
			cnt_collect <= 3'd0;
		
	
	//对 collect_judge 传入数据判断信号进行编写，判断数据是：1 or 0
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			collect_judge <= 4'd0;
		else if(cnt_bit_change_en == 1'b1)
			begin 
				if(cnt_collect_judge == cnt_collect_judge_max - 2)
					collect_judge <= collect_judge + nedge_txd[0];
				else 
					collect_judge <= collect_judge;
			end 
		else 
			collect_judge <= 4'd0;
			
	
			
	//对数据信号进行提取判断并缓存			利用状态机对数据进行提取和判断数据是 1 or 0 
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			collect_data <= 8'd0;
		else if(cnt_bit_en == 1'b1)
			begin 
				case(cnt_bit_collect)
					1	:	
							begin 
								if((cnt_collect == 3'd7) && (cnt_collect_judge == cnt_collect_judge_max - 1))
									begin 
										if(collect_judge >= 4'd4)
											collect_data[0] <= 1'b1;
										else 
											collect_data[0] <= 1'b0;
									end
								 else 
									collect_data[0] <= collect_data[0];
							end 
					2	:
							begin 
								if((cnt_collect == 3'd7) && (cnt_collect_judge == cnt_collect_judge_max - 1))
									begin 
										if(collect_judge >= 4'd4)
											collect_data[1] <= 1'b1;
										else 
											collect_data[1] <= 1'b0;
									end
								 else 
									collect_data[1] <= collect_data[1];
							end 
					3	:
							begin 
								if((cnt_collect == 3'd7) && (cnt_collect_judge == cnt_collect_judge_max - 1))
									begin 
										if(collect_judge >= 4'd4)
											collect_data[2] <= 1'b1;
										else 
											collect_data[2] <= 1'b0;
									end
								 else 
									collect_data[2] <= collect_data[2];
							end 
					4	:
							begin 
								if((cnt_collect == 3'd7) && (cnt_collect_judge == cnt_collect_judge_max - 1))
									begin 
										if(collect_judge >= 4'd4)
											collect_data[3] <= 1'b1;
										else 
											collect_data[3] <= 1'b0;
									end
								 else 
									collect_data[3] <= collect_data[3];
							end 
					5	:
							begin 
								if((cnt_collect == 3'd7) && (cnt_collect_judge == cnt_collect_judge_max - 1))
									begin 
										if(collect_judge >= 4'd4)
											collect_data[4] <= 1'b1;
										else 
											collect_data[4] <= 1'b0;
									end
								 else 
									collect_data[4] <= collect_data[4];
							end 
					6	:
							begin 
								if((cnt_collect == 3'd7) && (cnt_collect_judge == cnt_collect_judge_max - 1))
									begin 
										if(collect_judge >= 4'd4)
											collect_data[5] <= 1'b1;
										else 
											collect_data[5] <= 1'b0;
									end
								 else 
									collect_data[5] <= collect_data[5];
							end 
					7	:
							begin 
								if((cnt_collect == 3'd7) && (cnt_collect_judge == cnt_collect_judge_max - 1))
									begin 
										if(collect_judge >= 4'd4)
											collect_data[6] <= 1'b1;
										else 
											collect_data[6] <= 1'b0;
									end
								 else 
									collect_data[6] <= collect_data[6];
							end 
					8	:
							begin 
								if((cnt_collect == 3'd7) && (cnt_collect_judge == cnt_collect_judge_max - 1))
									begin 
										if(collect_judge >= 4'd4)
											collect_data[7] <= 1'b1;
										else 
											collect_data[7] <= 1'b0;
									end
								 else 
									collect_data[7] <= collect_data[7];
							end 
					default :	collect_data <= collect_data;
				endcase
			end 
		else 
			collect_data <= 8'd0;
			
	//对接收到的数据进行提取
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			data_accept <= 8'd0;
		else if((cnt_bit_en == 1'b1) && (cnt_bit == cnt_bit_max - 1) && (cnt_bit_collect == 4'd9))
			data_accept <= collect_data;
		else 
			data_accept <= data_accept;
			
	always @(posedge clk or negedge ret_n)
		if(!ret_n)
			uart_end <= 1'b0;
		else if(cnt_bit == cnt_bit_max - 1 && cnt_bit_collect == 4'd9)
			uart_end <= 1'b1;
		else 	
			uart_end <= 1'b0;
			
			
endmodule 




























